package com.cilico.single.waterfall;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.util.ByteArrayBuffer;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.widget.Toast;

import com.cilico.single.ConfigManager;
import com.cilico.single.Mid;
import com.cilico.single.utils.Utils;
import com.cilico.single.view.BaseView;

/**
 * 图片加工�?
 */
public class ImageUtil {
	
	/**
	 * 通过路径获取输入�?
	 * 
	 * @param path 路径
	 * @return 输入�?
	 * @throws Exception 异常
	 */
	public static InputStream getRequest(String path) throws Exception {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(3000);
		if (conn.getResponseCode() == 200) {
			return conn.getInputStream();
		}
		return null;
	}

	/**
	 * 从流中读取二进制数据
	 * 
	 * @param inStream 输入�?
	 * @return 二进制数�?
	 * @throws Exception 异常
	 */
	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[4096];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		return outSteam.toByteArray();
	}

	/**
	 * 把一个路径转换成Drawable对象
	 * 
	 * @param url 路径
	 * @return Drawable对象
	 */
	public static Drawable loadImageFromUrl(String url) {
		URL m;
		InputStream i = null;
		try {
			m = new URL(url);
			i = (InputStream) m.getContent();
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Drawable d = Drawable.createFromStream(i, "src");
		return d;
	}

	/**
	 * 把一个路径转换成Drawable对象
	 * 
	 * @param url 字符串路�?
	 * @return Drawable对象
	 * @throws Exception 异常
	 */
	public static Drawable getDrawableFromUrl(String url) throws Exception {
		return Drawable.createFromStream(getRequest(url), null);
	}

	/**
	 * 从路径中得到位图
	 * 
	 * @param url 字符串路�?
	 * @return 位图
	 * @throws Exception 异常
	 */
	public static Bitmap getBitmapFromUrl(String url) throws Exception {
		byte[] bytes = getBytesFromUrl(url);
		return byteToBitmap(bytes);
	}

	/**
	 * 从路径中得到圆角位图
	 * 
	 * @param url 字符串路�?
	 * @param pixels  圆角弧度
	 * @return 圆角位图
	 * @throws Exception 异常
	 */
	public static Bitmap getRoundBitmapFromUrl(String url, int pixels) throws Exception {
		byte[] bytes = getBytesFromUrl(url);
		Bitmap bitmap = byteToBitmap(bytes);
		return toRoundCorner(bitmap, pixels);
	}

	/**
	 * 从路径中得到圆角Drawable对象
	 * 
	 * @param url 字符串路�?
	 * @param pixels 圆角弧度
	 * @return 圆角Drawable对象
	 * @throws Exception 异常
	 */
	public static Drawable geRoundDrawableFromUrl(String url, int pixels) throws Exception {
		byte[] bytes = getBytesFromUrl(url);
		BitmapDrawable bitmapDrawable = (BitmapDrawable) byteToDrawable(bytes);
		return toRoundCorner(bitmapDrawable, pixels);
	}

	/**
	 * 从路径中得到二进制数�?
	 * 
	 * @param url  字符串路�?
	 * @return 二进制数�?
	 * @throws Exception 异常
	 */
	public static byte[] getBytesFromUrl(String url) throws Exception {
		byte[] data = null;
		String name = url.substring(url.lastIndexOf("/") + 1);
		if (null != url && url.toLowerCase().startsWith("local://")) {
			// 读取本地缓存
			data = readLocalImage(getFileDir(ConfigManager.currentView_), name);
		} else {
			// 通过网络下载
			data = readInputStream(getRequest(url));
		}
		Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
		bitmap = Utils.scalBitmap(bitmap);
		data = Bitmap2Bytes(bitmap);
		saveImage(getFileDir(ConfigManager.currentView_), name, data);
		return data;
	}

	/**
	 * 从二进制数据中得到位�?
	 * 
	 * @param byteArray 二进制数�?
	 * @return 位图
	 */
	public static Bitmap byteToBitmap(byte[] byteArray) {
		if (byteArray.length != 0) {
			return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
		} else {
			return null;
		}
	}

	/**
	 * 从二进制数据中得到Drawable对象
	 * 
	 * @param byteArray 二进制数�?
	 * @return Drawable对象
	 */
	public static Drawable byteToDrawable(byte[] byteArray) {
		ByteArrayInputStream ins = new ByteArrayInputStream(byteArray);
		return Drawable.createFromStream(ins, null);
	}

	/**
	 * 把位图转换称二进制数�?
	 * 
	 * @param bm 位图
	 * @return 二进制数�?
	 */
	public static byte[] Bitmap2Bytes(Bitmap bm) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}

	/**
	 * 把Drawable对象转换称位�?
	 * 
	 * @param drawable Drawable对象
	 * @return 位图
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {

		Bitmap bitmap = Bitmap.createBitmap(
						drawable.getIntrinsicWidth(),
						drawable.getIntrinsicHeight(),
						drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
		drawable.draw(canvas);
		return bitmap;
	}

	/**
	 * 图片去色,返回灰度图片
	 * 
	 * @param bmpOriginal 传入的图�?
	 * @return 去色后的图片
	 */
	public static Bitmap toGrayscale(Bitmap bmpOriginal) {
		int width, height;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();
		Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
		Canvas c = new Canvas(bmpGrayscale);
		Paint paint = new Paint();
		ColorMatrix cm = new ColorMatrix();
		cm.setSaturation(0);
		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);
		c.drawBitmap(bmpOriginal, 0, 0, paint);
		return bmpGrayscale;
	}

	/**
	 * 去色同时加圆�?
	 * 
	 * @param bmpOriginal  原图
	 * @param pixels  圆角弧度
	 * @return 修改后的图片
	 */
	public static Bitmap toGrayscale(Bitmap bmpOriginal, int pixels) {
		return toRoundCorner(toGrayscale(bmpOriginal), pixels);
	}

	/**
	 * 把位图变成圆角位�?
	 * 
	 * @param bitmap  �?��修改的位�?
	 * @param pixels  圆角的弧�?
	 * @return 圆角位图
	 */
	public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);
		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = pixels;
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);
		return output;
	}

	/**
	 * 将BitampDrawable转换成圆角的BitampDrawable
	 * 
	 * @param bitmapDrawable  原生BitampDrawable对象
	 * @param pixels  圆角弧度
	 * @return 圆角BitampDrawable对象
	 */
	public static BitmapDrawable toRoundCorner(BitmapDrawable bitmapDrawable, int pixels) {
		Bitmap bitmap = bitmapDrawable.getBitmap();
		bitmapDrawable = new BitmapDrawable(toRoundCorner(bitmap, pixels));
		return bitmapDrawable;
	}

	/**
	 * 图片水印生成的方�?
	 * 
	 * @param src 源图片位�?
	 * @param watermark 水印图片位图
	 * @return 返回�?��加了水印的图�?
	 */
	public static Bitmap createBitmap(Bitmap src, Bitmap watermark) {
		if (src == null)
			return null;
		int w = src.getWidth();
		int h = src.getHeight();
		int ww = watermark.getWidth();
		int wh = watermark.getHeight();
		Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建�?��新的和SRC长度宽度�?��的位�?
		Canvas cv = new Canvas(newb);// 初始化画�?
		cv.drawBitmap(src, 0, 0, null);// �?0�?坐标�?��画入src
		cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印
		cv.save(Canvas.ALL_SAVE_FLAG);// 保存，用来保存Canvas的状态�?save之后，可以调用Canvas的平移�?放缩、旋转�?错切、裁剪等操作�?
		cv.restore();// 存储，用来恢复Canvas之前保存的状态�?防止save后对Canvas执行的操作对后续的绘制有影响�?
		return newb;
	}
	
	/**
	 * 将本地图片转换成输入�?
	 * @param fieDir
	 * @param name
	 * @return
	 * @throws IOException
	 */
	public static byte[] readLocalImage(String fieDir, String name) throws IOException {
		ByteArrayBuffer buffer = null;
		String realPath = fieDir.concat(File.separator).concat(name);
		File file = new File(realPath);
		if (!file.exists()) {
			return null;
		}
		InputStream inputstream = new FileInputStream(file);
		buffer = new ByteArrayBuffer(1024);
		byte[] tmp = new byte[1024];
		int len;
		while (((len = inputstream.read(tmp)) != -1)) {
			buffer.append(tmp, 0, len);
		}
		inputstream.close();
		return buffer.toByteArray();
	}

    /**
     * �?��SDcard状�?
     * @return boolean
     */ 
    public static boolean hasSDCard() {
        return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    }
    
    /**
     * 获取图片保存目录
     * @param context
     * @return  文件保存目录
     */ 
    public static String getFileDir(Context context) {
        String filePath;
        if (hasSDCard()) {
            filePath = Environment.getExternalStorageDirectory().toString();
        } else {
            filePath = context.getCacheDir().getAbsolutePath().toString();
        }
        filePath = filePath.concat("/cilico/temp");
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return filePath;
    }
    
    /**
     * 将图片以文件的形式保存下�?
     * @param path
     * @param name
     * @param data
     * @throws IOException
     */
    public static void saveImage(String path, String name, byte[] data) throws IOException {
    	// 写入本地文件
        File file = new File(path.concat(File.separator).concat(name));
        if (!file.exists()) {
            file.createNewFile();
        }
        FileOutputStream outStream = new FileOutputStream(file);
        outStream.write(data);
        outStream.close();
    
        // 定期清空
        cutDownCaches(path);
    }

    /**
     * 定期对缓存图片进行删�?
     * @param path
     * @throws IOException
     */
	public static void cutDownCaches(String path) throws IOException {
		File file = new File(path);
		File[] files = file.listFiles();
		if (files.length > 100) {
			for (int i = 50; i < files.length; i++) {
				files[i].delete();
			}
		}
	}
	
	/**
	 * 删除图片目录。
	 * @author lvke
	 * Email: lvke@live.cn
	 * 2014-4-4下午6:26:43
	 * @param bv
	 */
	public static void clearPicture(BaseView bv){
		//删除SD卡上目录文件
		boolean a = false;
		String path = getFileDir(bv);
		a = delAllFiles(path);
		//删除程序目录下的文件
		boolean b = false;
		String path1 = Mid.getFileDir(bv);
		b = delAllFiles(path1);
		//特殊处理temp文件下面直接存储图片的问题
		String pp = path1.substring(0, path1.lastIndexOf("/"));
		if (pp != null && !pp.equals("")) {
			delAllFiles(pp);
		}
		if (a && b) {
			Toast.makeText(bv, "缓存清理成功", Toast.LENGTH_LONG).show();
		}else {
			if (!a) {
				Toast.makeText(bv, "找不到SD卡", Toast.LENGTH_LONG).show();
			}else if(!b) {
				Toast.makeText(bv, "优化失败", Toast.LENGTH_LONG).show();
			}
		}
	}
	/**
	 * 删除文件夹下面所有的文件
	 * @author lvke
	 * Email: lvke@live.cn
	 * 2014-4-10下午3:56:46
	 * @param path
	 * @return
	 */
	public static boolean delAllFiles(String path){
		boolean b = false;
		File file = new File(path);
		if (!file.exists()) {
			return b;
		}
		if (!file.isDirectory()) {
			return b;
		}
		String[] tempList = file.list();
		File tempFile = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				tempFile = new File(path + tempList[i]);
			}else {
				tempFile = new File(path + File.separator + tempList[i]);
			}
			if (tempFile.isFile()) {
				b = tempFile.delete();
			}
		}
		return true;
	}
}
